package com.fingard.dsp.bank.directbank.specialDeal;

import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.*;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.text.StringHelper;

/**
 * 明细缓存类
 */
public class TransHelper implements ITcpClient {

    private static String queryActInfo = "select auto_sync_curr_trans autocurtrans,auto_sync_his_trans autohistrans from tbl_dspcl_act_info where act_num=?";
    private static String insertActCurInfo = "insert into tbl_dspcl_act_info (urid,bank_code,entity,system_code,act_num,act_cur,act_area,auto_sync_curr_trans) values (?,?,?,?,?,?,?,'1')";
    private static String insertActHisInfo = "insert into tbl_dspcl_act_info (urid,bank_code,entity,system_code,act_num,act_cur,act_area,auto_sync_his_trans) values (?,?,?,?,?,?,?,'1')";
    private static String updateActCurInfo = "update tbl_dspcl_act_info set entity=?,system_code=?,act_cur=?,act_area=?,auto_sync_curr_trans=1 where act_num=?";
    private static String updateActHisInfo = "update tbl_dspcl_act_info set entity=?,system_code=?,act_cur=?,act_area=?,auto_sync_his_trans=1 where act_num=?";
    private static String updateActAutoCurTrans = "update tbl_dspcl_act_info set auto_sync_curr_trans=? where act_num=?";
    private static String updateActAutoHisTrans = "update tbl_dspcl_act_info set auto_sync_his_trans=? where act_num=?";
    private static String insertTransCache = "insert into tbl_dspcl_trans_cache (urid,act_num,trans_date,trans_type,seq_no,unique_code,cache_data) values(?,?,?,?,?,?,?)";
    private static String queryHisTransCache = "select cache_data cachedata from tbl_dspcl_trans_cache where act_num=? and trans_date>=? and trans_date<=? and trans_type='7516' order by trans_date,seq_no";
    private static String queryCurTransCache = "select cache_data cachedata from tbl_dspcl_trans_cache where act_num=? and trans_date=? and seq_no>=? and trans_type='7515' order by seq_no";
    private static String queryMaxSeqNo = "select max(seq_no) from tbl_dspcl_trans_cache where act_num=? and trans_date=? and trans_type=?";
    private static String queryActiveCurAct = "select bank_code bankcode,entity corporation,system_code actgroup,act_num actnum,act_cur actcur,act_area actarea from tbl_dspcl_act_info where auto_sync_curr_trans=1";
    private static String queryActiveHisAct = "select bank_code bankcode,entity corporation,system_code actgroup,act_num actnum,act_cur actcur,act_area actarea from tbl_dspcl_act_info where auto_sync_his_trans=1";
    private static String joinFlag = "||";
    private static String defaultEntity = "5000001";
    private static String defaultSystemCode = "Default";
    private static String curTransReqFormat = "<ATSYH>\n" +
            "  <TransReq>\n" +
            "    <BankCode>%s</BankCode>\n" +
            "    <TransType>7515</TransType>\n" +
            "    <TransSeqID>%s</TransSeqID>\n" +
            "    <Entity>%s</Entity>\n" +
            "    <SystemCode>%s</SystemCode>\n" +
            "    <TransTime>%s</TransTime>\n" +
            "    <TransParam>\n" +
            "      <ActArea>%s</ActArea>\n" +
            "      <ActCur>%s</ActCur>\n" +
            "      <ActNum>%s</ActNum>\n" +
            "      <IsNonStandard>0</IsNonStandard>\n" +
            "      <IsSpecialAct>0</IsSpecialAct>\n" +
            "      <IsReqFromDsp>1</IsReqFromDsp>\n" +
            "      <QueryUrid>0</QueryUrid>\n" +
            "    </TransParam>\n" +
            "  </TransReq>\n" +
            "</ATSYH>";
    private static String hisTransReqFormat = "<ATSYH>\n" +
            "  <TransReq>\n" +
            "    <BankCode>%s</BankCode>\n" +
            "    <TransType>7516</TransType>\n" +
            "    <TransSeqID>%s</TransSeqID>\n" +
            "    <Entity>%s</Entity>\n" +
            "    <SystemCode>%s</SystemCode>\n" +
            "    <TransTime>%s</TransTime>\n" +
            "    <TransParam>\n" +
            "      <ActArea>%s</ActArea>\n" +
            "      <ActCur>%s</ActCur>\n" +
            "      <ActNum>%s</ActNum>\n" +
            "      <IsNonStandard>0</IsNonStandard>\n" +
            "      <DateFrom>%s</DateFrom>\n" +
            "      <DateTo>%s</DateTo>\n" +
            "      <IsReqFromDsp>1</IsReqFromDsp>\n" +
            "    </TransParam>\n" +
            "  </TransReq>\n" +
            "</ATSYH>";
    private static String queryTransExist = "select seq_no from tbl_dspcl_trans_cache where act_num=? and trans_type=? and unique_code=? ";


    public static void insertOrUpdateActInfo(boolean isCurTransQuery, String bankCode, String corporation, String actGroup, String actNum, String actCur, String actArea) throws Exception {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();
            Map<String, Object> actMap = JDBCHelper.execQuerySingle(dbConn, queryActInfo, new Object[]{actNum});
            corporation = StringHelper.isNullOrEmpty(corporation) ? defaultEntity : corporation;
            actGroup = StringHelper.isNullOrEmpty(actGroup) ? defaultSystemCode : actGroup;
            if (actMap != null && actMap.size() > 0) {
                String tmpSql = "";
                if (isCurTransQuery) {
                    if (!String.valueOf(actMap.get("autocurtrans")).equals("1")) {
                        tmpSql = updateActCurInfo;
                    }
                } else {
                    if (!String.valueOf(actMap.get("autohistrans")).equals("1")) {
                        tmpSql = updateActHisInfo;
                    }
                }

                if (!StringHelper.isNullOrEmpty(tmpSql)) {
                    JDBCHelper.update(dbConn, tmpSql, new Object[]{corporation, actGroup, actCur, actArea, actNum});
                }
            } else {
                String tmpSql = isCurTransQuery ? insertActCurInfo : insertActHisInfo;
                JDBCHelper.update(dbConn, tmpSql, new Object[]{UUID.randomUUID().toString().replace("-", ""), bankCode, corporation, actGroup, actNum, actCur, actArea});
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public static boolean updateAutoTrans(boolean isCurTrans, boolean isAuto, String actNum) throws Exception {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();

            Map<String, Object> actMap = JDBCHelper.execQuerySingle(dbConn, queryActInfo, new Object[]{actNum});
            if (actMap == null || actMap.size() == 0) {
                return true;
            } else {
                int result = JDBCHelper.update(dbConn, isCurTrans ? updateActAutoCurTrans : updateActAutoHisTrans, new Object[]{isAuto ? "1" : "0", actNum});
                return result > 0;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public static int getMaxSeqNo(String p_actNum, String p_transDate, String p_transType) throws Exception {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            java.util.Date transDate = null;
            try {
                transDate = format.parse(p_transDate);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (transDate != null) {
                java.sql.Date cacheDate = new java.sql.Date(transDate.getTime());
                Map<String, Object> transCacheMap = JDBCHelper.execQuerySingle(dbConn, queryMaxSeqNo, new Object[]{p_actNum, cacheDate, p_transType});
                if (transCacheMap != null && transCacheMap.size() > 0) {
                    String seqNo = String.valueOf(transCacheMap.get("max(seq_no)"));
                    if (seqNo.equals("null") || StringHelper.isNullOrEmpty(seqNo)) {
                        return 0;
                    }
                    return Integer.parseInt(seqNo);
                }
            }
            return 0;
        } catch (Exception ex) {
            ex.printStackTrace();
            return 0;
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public static List<RetAtsTransDetail> getHisTransCache(String p_actNum, String p_dateFrom, String p_dateTo) throws Exception {
        List<RetAtsTransDetail> tmpDetails = new ArrayList<RetAtsTransDetail>();
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();

            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            java.util.Date dateFrom = null;
            java.util.Date dateTo = null;
            try {
                dateFrom = format.parse(p_dateFrom);
                dateTo = format.parse(p_dateTo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (dateFrom != null && dateTo != null) {
                java.sql.Date cacheDateFrom = new java.sql.Date(dateFrom.getTime());
                java.sql.Date cacheDateTo = new java.sql.Date(dateTo.getTime());

                List<Map<String, Object>> transCacheList = JDBCHelper.execQuery(dbConn, queryHisTransCache, new Object[]{p_actNum, cacheDateFrom, cacheDateTo});
                if (transCacheList != null && transCacheList.size() > 0) {
                    for (Map<String, Object> transCacheMap : transCacheList) {
                        RetAtsTransDetail tmpDetail = new RetAtsTransDetail();
                        tmpDetail.fromDB(String.valueOf(transCacheMap.get("cachedata")));
                        tmpDetails.add(tmpDetail);
                    }
                }
            }
            return tmpDetails;
        } catch (Exception ex) {
            ex.printStackTrace();
            return tmpDetails;
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public static List<RetAtsTransDetail> getCurTransCache(String p_actNum, String p_date, int p_seqNo) throws Exception {
        List<RetAtsTransDetail> tmpDetails = new ArrayList<RetAtsTransDetail>();
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();

            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            java.util.Date tranDate = null;
            try {
                tranDate = format.parse(p_date);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (tranDate != null) {
                java.sql.Date cacheDate = new java.sql.Date(tranDate.getTime());
                List<Map<String, Object>> transCacheList = JDBCHelper.execQuery(dbConn, queryCurTransCache, new Object[]{p_actNum, cacheDate, p_seqNo});
                if (transCacheList != null && transCacheList.size() > 0) {
                    for (Map<String, Object> transCacheMap : transCacheList) {
                        RetAtsTransDetail tmpDetail = new RetAtsTransDetail();
                        tmpDetail.fromDB(String.valueOf(transCacheMap.get("cachedata")));
                        tmpDetails.add(tmpDetail);
                    }
                }
            }
            return tmpDetails;
        } catch (Exception ex) {
            ex.printStackTrace();
            return tmpDetails;
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public static void insertTransCaches(String p_transType, RetAtsTransDetail p_retAtsTransDetail) throws Exception {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

            Map<String, Object> transMap = JDBCHelper.execQuerySingle(dbConn, queryTransExist, new Object[]{p_retAtsTransDetail.actNum, p_transType, p_retAtsTransDetail.actNum + joinFlag + p_retAtsTransDetail.recAccNum + joinFlag + p_retAtsTransDetail.recAccName + joinFlag + p_retAtsTransDetail.tranTime + joinFlag + p_retAtsTransDetail.cdFlag + joinFlag + p_retAtsTransDetail.tranAmt + joinFlag + p_retAtsTransDetail.abstr + joinFlag});
            if (transMap != null && transMap.size() > 0) {
                return;
            }

            Date tranDate = null;
            try {
                tranDate = format.parse(p_retAtsTransDetail.tranDate);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (tranDate != null) {
                java.sql.Date cacheDate = new java.sql.Date(tranDate.getTime());
                p_retAtsTransDetail.dspUrid = getMaxSeqNo(p_retAtsTransDetail.actNum, p_retAtsTransDetail.tranDate, p_transType) + 1 + "";
                JDBCHelper.update(dbConn, insertTransCache, new Object[]{UUID.randomUUID().toString().replace("-", ""), p_retAtsTransDetail.actNum, cacheDate, p_transType, Integer.parseInt(p_retAtsTransDetail.dspUrid), p_retAtsTransDetail.actNum + joinFlag + p_retAtsTransDetail.recAccNum + joinFlag + p_retAtsTransDetail.recAccName + joinFlag + p_retAtsTransDetail.tranTime + joinFlag + p_retAtsTransDetail.cdFlag + joinFlag + p_retAtsTransDetail.tranAmt + joinFlag + p_retAtsTransDetail.abstr + joinFlag, p_retAtsTransDetail.toDB()});
            }
        } catch (Exception ex) {
            throw new Exception(ex);
        } finally {
            if (dbConn != null) {
                dbConn.close();
            }
        }
    }

    public void queryHisFromBank() {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();
            List<Map<String, Object>> actsList = JDBCHelper.execQuery(dbConn, queryActiveHisAct, new Object[]{});
            if (actsList != null && actsList.size() > 0) {
                for (Map<String, Object> act : actsList) {
                    Date currDate = new Date();
                    Calendar tmpCalendar = Calendar.getInstance();
                    tmpCalendar.setTime(currDate);
                    tmpCalendar.add(Calendar.DATE, -1);
                    int tmpIntDate = Integer.parseInt(Format.Date8Format.format(tmpCalendar.getTime()));
                    String sendContent = String.format(hisTransReqFormat, act.get("bankcode"), Format.DateTime17Format.format(currDate), act.get("corporation"), act.get("actgroup"), Format.DateTimeFormat.format(currDate), act.get("actarea"), act.get("actcur"), act.get("actnum"), tmpIntDate, tmpIntDate);
                    sendReqToDsp(sendContent);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (dbConn != null) {
                    dbConn.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public void queryCurFromBank() {
        Connection dbConn = null;
        try {
            dbConn = FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection();
            List<Map<String, Object>> actsList = JDBCHelper.execQuery(dbConn, queryActiveCurAct, new Object[]{});
            if (actsList != null && actsList.size() > 0) {
                for (Map<String, Object> act : actsList) {
                    Date currDate = new Date();
                    String sendContent = String.format(curTransReqFormat, act.get("bankcode"), Format.DateTime17Format.format(currDate), act.get("corporation"), act.get("actgroup"), Format.DateTimeFormat.format(currDate), act.get("actarea"), act.get("actcur"), act.get("actnum"));
                    sendReqToDsp(sendContent);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (dbConn != null) {
                    dbConn.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private static String getCharset() {
        return "GBK";
    }

    public void sendReqToDsp(String p_req) {
        try {
            TcpPortClient tmpClient = new TcpPortClient("127.0.0.1", FGBiz.dspCenter.dspSet.listenerPort, this);

            byte[] tmpBytesBody = p_req.getBytes(getCharset());

            String tmpStrLen = String.format("% 8d", tmpBytesBody.length);

            String tmpSendHead = "Content-Length:" + tmpStrLen + "\r\n";
            byte[] tmpBytesHead = tmpSendHead.getBytes(getCharset());

            byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
            System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
            System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

            tmpClient.sendMessage(tmpBytesSend);
        } catch (Exception ex) {
            ex.printStackTrace();
            ;
        }

    }

    @Override
    public void getContentLength(TcpReceiver p_receiver) throws Exception {

    }
}
